package com.ynet.middleground.oss.model;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.util.Calendar;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.aliyun.oss.OSSClient;
import com.ynet.core.exception.BusinessException;
import com.ynet.core.log.IfpLogger;
import com.ynet.file.service.FileService;
import com.ynet.file.starter.FileServiceConfiguration;
import com.ynet.middleground.oss.utils.FileUtil;
import com.ynet.middleground.riskmanage.bean.GetFileReq;
import com.ynet.middleground.riskmanage.bean.UploadReq;
import com.ynet.middleground.riskmanage.dto.FileInfoDTO;

/**
 * @author liulx
 * @description 上传文件至 OSS 服务业务实现
 * @date 2020-09-11 15:53
 */
@Component
public class OssModel {

    /**
     * OSS id
     */
    public static final String OSS_ID = "oss";

    @Autowired
    private FileService fileService;

    @Autowired
    private FileServiceConfiguration fileServiceConfiguration;

    /**
     * 上传文件至 OSS
     *
     * @param req 上传文件请求信息
     * @return 文件 OSS 短路径地址
     */
    public String upload(UploadReq req) {
        String fileBase64 = req.getFileBase64();
        String fileName = req.getName();
        byte[] bytes = Base64.decodeBase64(fileBase64);
        String fileUrl = fileService.uploadFile(OSS_ID, new ByteArrayInputStream(bytes),
            Calendar.getInstance().getTimeInMillis() + fileName, getOssBucketName());
        IfpLogger.info(Thread.currentThread().getStackTrace()[1].getMethodName(), "上传文件 OSS 地址: {}", fileUrl);
        // 直接返回短路径地址
        return fileUrl;
        // return getFullUrl(fileUrl);
    }

    /**
     * 根据文件地址下载文件
     *
     * @param req 获取文件请求信息
     * @return 文件流
     */
    public FileInfoDTO getFileByUrl(GetFileReq req) {
        String suffix = FileUtil.getFileSuffix(req.getUrl());
        if (StringUtils.isBlank(suffix)) {
            throw new BusinessException("文件后缀错误", "ECRM0002");
        }
        File file = FileUtil.getFileByUrl(transferFileUrl(req.getUrl()), "." + suffix);
        FileInfoDTO fileInfoDTO = new FileInfoDTO();
        String base64String = Base64.encodeBase64String((FileUtil.fileToByte(file)));
        fileInfoDTO.setFileBase64(base64String);
        return fileInfoDTO;
    }

    /**
     * 获取上传 OSS 后文件的完整地址
     *
     * @param fileUrl oss 文件短地址
     * @return 完整地址
     */
    public String getFullUrl(String fileUrl) {
        String endpoint = fileServiceConfiguration.getConfigs().get(0).getOssConfig().getEndpoint();
        // 之前 OSS 环境使用该方式
        return endpoint.substring(0, endpoint.lastIndexOf("/")) + "/" + fileUrl;

        // 205 云下环境使用以下方式
        /*String str[] = fileUrl.split("/");
        fileUrl = endpoint.substring(0, endpoint.lastIndexOf("/") + 1) + "" + str[0] + "."
            + endpoint.substring(endpoint.lastIndexOf("/") + 1) + "/" + str[1];
        return fileUrl;*/
    }

    /**
     * 获取 oss bucketName
     *
     * @return bucketName
     */
    public String getOssBucketName() {
        // 之前 OSS 环境使用该方式
        OSSClient ossClient = (OSSClient)fileService.getOriginClient(OSS_ID);
        String path = ossClient.getEndpoint().getPath();
        return path.substring(path.indexOf("/") + 1);

        // 205 云下环境使用以下方式
        // return "zhongtai-jk";
    }

    /**
     * 获取 OSS 域名
     *
     * @return oss 域名地址
     */
    public String getOssHost() {
        OSSClient ossClient = (OSSClient)fileService.getOriginClient("oss");
        return ossClient.getEndpoint().getHost();
    }

    /**
     * 文件路径地址转换，获取文件完整路径
     *
     * <pre>
     * 如果文件地址包含 OSS 域名路径，则认为是全路径，返回入参地址；
     * 否则认为文件是短路径，则将入参地址转换成全路径地址
     * </pre>
     *
     * @param path 文件地址
     * @return 文件完整路径
     */
    public String transferFileUrl(String path) {
        return path.contains(getOssHost()) ? path : getFullUrl(path);
    }

}
